package com.zebra.remoting.config;


import com.zebra.common.ExpiredExitMessage;
import com.zebra.common.ZbmMessage;
import com.zebra.remoting.protocol.*;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


public enum BasisCommandCode implements CommandCode {

    PUSHCMD(101,      ProcessorType.PUSH,  CommandType.GAME, PoolType.DISRUPTOR,   EmptyMessage.class), //该命令号 用于占位 TMS 向 网关推送消息 ，命令号是随意制定；用该命令号,
    PING(111,         PingMessage.class),
    REGISTER(222,     RegisterConnectMessage.class),  //注册中心向 GW TMS 发消息注册, GW 向TMS 发消息注册
    RATOTMS(232,      GwRegisterMessage.class), //TMS 启动 如果有GW  RA 则向 GW 发消息，让GW 去链接TMS
    LINKSTORA(333,    LINKSTORAmessage.class), //网关 向注册中心 发 当前链接信息 不需要回消息
    ONNUMTORA(330,    ONNUMTORAmessage.class),  //GW TMS  发消息 更改 在线人数
    GWRTMS(353,       GWRTMSmessage.class), //网关向 注册中心 发消息 注册中心 返回 GwRegisterMessage
    TMSOFFON(373,     EmptyMessage.class),  //注册中心 向网关发 TMS 上线 下线消息; TMS 更改serverInfo 在线状态
    //业务相关层
    TMSTORA(100,       EmptyMessage.class), // Black Hawk
    SWITCHTMS(500,    EmptyMessage.class), //大厅可以切换服务器 目前只设计了大厅;
    ASKTMS(600,       AskTmsRequestMessage.class), //GW 向注册中心 索要 serverId [RA 根据权重负载服务器]
    OFFLINE(610,      EmptyMessage.class ), //GW 向TMS 发 玩家断开消息;
    //广播消息,

    //900 开头业务 推送消息使用,
    REPEAT_LOGIN(901,  EmptyMessage.class),  //推送 重复登录； 登录服-->注册中心-->网关 【消息体业务层自定义】
    PLAYING(902,        ProcessorType.GM, CommandType.GAME,  PoolType.DISRUPTOR, EmptyMessage.class),  //推送 进入游戏 校验 是否在游戏中 【消息体业务层自定义】
    ZBM(903,            ZbmMessage.class),
    EXPIRED(904,       ProcessorType.GM, CommandType.BASIS, PoolType.DISRUPTOR, ExpiredExitMessage.class), //过期退出
    OVERHAULED(905,    ProcessorType.GM, CommandType.BASIS, PoolType.DISRUPTOR, EmptyMessage.class)  // 服务器处于维护状态； 推消息给玩家 提示返回大厅
    ;

    private int cmd ;
    private ProcessorType processorType;
    private PoolType poolType;
    private boolean verifyType;
    private final Class request;
    private CommandType commandType;


    BasisCommandCode(int cmd, ProcessorType processorType, CommandType commandType, PoolType poolType, Class request){
        this.cmd = cmd;
        this.processorType = processorType;
        this.poolType = poolType;
        this.verifyType = false;
        this.request = request;
        this.commandType = commandType;
    }


    BasisCommandCode(int cmd, Class request){
        this.cmd = cmd;
        this.processorType = ProcessorType.GM;
        this.poolType = PoolType.NOT;
        this.verifyType = false;
        this.request = request;
        this.commandType = CommandType.BASIS;
    }

    @Override
    public int cmd() {
        return this.cmd;
    }

    @Override
    public ProcessorType processorType() {
        return this.processorType;
    }

    @Override
    public PoolType poolType() {
        return this.poolType;
    }

    @Override
    public boolean verifyType() {
        return verifyType;
    }

    @Override
    public CommandType commandType() {
        return this.commandType;
    }

    @Override
    public Class request() {
        return this.request;
    }


    //转换成 map
    private  static Map<Integer, CommandCode> handlerTypeMap = Arrays.stream(BasisCommandCode.values())
            .collect(Collectors.toMap(BasisCommandCode::cmd, rtype -> rtype));

    public  static CommandCode valueOfCode(int cmd){
        return  handlerTypeMap.get(cmd);
    }

    public  static Map<Integer, CommandCode> getMap(){
        return handlerTypeMap;
    }

    public static List<CommandProfile> toListProfile(){
       return handlerTypeMap.values().stream().map(c -> CommandProfile.builder()
                .cmd(c.cmd())
                .commandType(c.commandType().value())
                .processorType(c.processorType().value())
                .poolType(c.poolType().value())
                .verifyType(c.verifyType())
                .build()).collect(Collectors.toList());
    }

}
